package edu.zjucst.spb.domain;

import edu.zjucst.spb.constant.StageConstant;
import edu.zjucst.spb.domain.entity.SpbUser;
import edu.zjucst.spb.enums.PresetMessageEnum;
import edu.zjucst.spb.service.message.UserMessageService;
import edu.zjucst.spb.util.SpringContextUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static edu.zjucst.spb.constant.StageConstant.*;

/**
 * 通过状态机推进党员的发展状态
 */

public enum DevelopStateMachine {
    APPLYING(APPLICANT) {
        @Override
        public SpbUser update(SpbUser spbUser) {
            spbUser.setDevelopmentPhase(ACTIVIST.phase);
            System.out.println("已从【入党申请阶段】进入【积极分子阶段】");
            return spbUser;
        }
    },

    ACTIVIST(StageConstant.ACTIVIST) {
        @Override
        public SpbUser update(SpbUser spbUser) {
            spbUser.setDevelopmentPhase(DEVELOPING.phase);
            System.out.println("已从【积极分子阶段】进入【发展对象阶段】");
            // 这边推送一次
            UserMessageService userMessageService = (UserMessageService) SpringContextUtil.getBean("userMessageService");
            PresetMessageEnum  messageEnum = PresetMessageEnum.APPLY_TALK_RECORD_SUBMIT;
            userMessageService.sendPresetMessageRightNow(messageEnum.getFromUserNumber(), spbUser.getId(), messageEnum.getMessageId());
            return spbUser;
        }
    },

    DEVELOPING(DEVELOP) {
        @Override
        public SpbUser update(SpbUser spbUser) {
            spbUser.setDevelopmentPhase(PREPARE.phase);
            System.out.println("已从【发展对象阶段】进入【预备党员阶段】");
            return spbUser;
        }
    },

    PREPARE(StageConstant.PREPARE) {
        @Override
        public SpbUser update(SpbUser spbUser) {
            spbUser.setDevelopmentPhase(COMPLETED.phase);
            // TODO: 可以预留消息推送的接口
            System.out.println("已从【预备党员阶段】进入【正式党员阶段】");
            return spbUser;
        }
    },

    COMPLETED(OFFICIAL) {
        @Override
        public SpbUser update(SpbUser spbUser) {
            System.out.println("你已经是【正式党员阶段】");
            return spbUser;
        }
    };


    /**
     * 发展阶段名称
     */
    private final String phase;

    DevelopStateMachine(String phase) {
        this.phase = phase;
    }

    /**
     * way1: 流程推进并触发
     *
     * @param spbUser 状态机消费者
     */
    public abstract SpbUser update(SpbUser spbUser);


    /**
     * way2: 对流程进行管控的写法
     */
    static class AvailableStateJump {
        static HashMap<DevelopStateMachine, List<DevelopStateMachine>> machine = new HashMap<>();

        static {
            machine.put(APPLYING, new ArrayList<DevelopStateMachine>() {{
                add(ACTIVIST);
            }});

            machine.put(ACTIVIST, new ArrayList<DevelopStateMachine>() {{
                add(DEVELOPING);
            }});

            machine.put(DEVELOPING, new ArrayList<DevelopStateMachine>() {{
                add(PREPARE);
            }});

            machine.put(PREPARE, new ArrayList<DevelopStateMachine>() {{
                add(COMPLETED);
            }});
        }
    }

    /**
     * 是否可以从 fromState 推进成 toState
     */
    public static boolean canStep(DevelopStateMachine fromState, DevelopStateMachine toState) {
        return AvailableStateJump.machine.get(fromState).contains(toState);
    }
    /**
     * 根据目前阶段获取到对应的状态机对象
     */
    public static DevelopStateMachine getDevelopStateMachine(String phase){

        switch (phase){
            case StageConstant.APPLICANT: return DevelopStateMachine.APPLYING;
            case StageConstant.ACTIVIST: return DevelopStateMachine.ACTIVIST;
            case StageConstant.DEVELOP: return DevelopStateMachine.DEVELOPING;
            case StageConstant.PREPARE: return DevelopStateMachine.PREPARE;
            case OFFICIAL: return DevelopStateMachine.COMPLETED;
            default: //异常处理
        }
        return null;
    }
}

